using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

namespace Voodoo.Sauce.Internal.Utils
{
	public class UnityThreadExecutor : MonoBehaviour
	{
		private const string TAG = "UnityThreadExecutor";

		private static UnityThreadExecutor _instance;

		private static Thread _mainThreadID;

		private static readonly List<Action> _eventsQueue = new List<Action>();

		private static volatile bool _eventsQueueEmpty = true;

		public static bool IsMainThread => _mainThreadID == Thread.CurrentThread;

		public static void Initialize()
		{
			if (!(_instance != null))
			{
				if (Application.isPlaying)
				{
					GameObject obj = new GameObject("UnityThreadExecutor")
					{
						hideFlags = HideFlags.HideAndDontSave
					};
					UnityEngine.Object.DontDestroyOnLoad(obj);
					_instance = obj.AddComponent<UnityThreadExecutor>();
				}
				_mainThreadID = Thread.CurrentThread;
			}
		}

		public void Awake()
		{
			UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
		}

		public static void SafeExecute(Action action)
		{
			try
			{
				Execute(action);
			}
			catch (Exception ex)
			{
				VoodooLog.LogError(Module.COMMON, "UnityThreadExecutor", ex.Message);
			}
		}

		public static void Execute(Action action)
		{
			if (IsMainThread)
			{
				action?.Invoke();
			}
			else
			{
				ExecuteInUpdate(action);
			}
		}

		public static void ExecuteInUpdate(Action action)
		{
			lock (_eventsQueue)
			{
				_eventsQueue.Add(action);
				_eventsQueueEmpty = false;
			}
		}

		public void Update()
		{
			if (_eventsQueueEmpty)
			{
				return;
			}
			List<Action> list = new List<Action>();
			lock (_eventsQueue)
			{
				list.AddRange(_eventsQueue);
				_eventsQueue.Clear();
				_eventsQueueEmpty = true;
			}
			foreach (Action item in list)
			{
				item();
			}
		}

		public void OnDisable()
		{
			_instance = null;
		}
	}
}
